//
// Created by hjie on 23-8-12.
//

#include "dump.h"
#include <cstdint>
#include <cstdio>
#include <libavutil/rational.h>
#include <libavutil/samplefmt.h>
#include <memory>
#include <chrono>
#include <sys/file.h>

DumpData::DumpData()
{

}

bool DumpData::InitDump()
{
    return true;
}

void DumpData::WriteData(const std::string &data)
{

}

void DumpData::WriteData(const uint8_t *data, int length)
{

}

FileDumpData::FileDumpData()
{
    m_file_desc = -1;
    m_init_status = false;
}

FileDumpData::~FileDumpData()
{
    if (m_init_status)
    {
        close(m_file_desc);
    }
}

bool FileDumpData::InitDump()
{
    auto now_time = std::chrono::system_clock::now();
    std::string filename = std::to_string(std::chrono::system_clock::to_time_t(now_time)) + ".txt";

    m_file_desc = open(filename.c_str(), O_CREAT | O_RDWR, 0666);
    if (m_file_desc >= 0)
    {
        m_init_status = true;
    }
    return m_init_status;
}

void FileDumpData::WriteData(const std::string &data)
{
    if (!m_init_status) return;
    char buf[data.size() + 128] = {0};
    int size = snprintf(buf, sizeof(buf) - 1, "%s.\n", data.c_str());
    write(m_file_desc, buf, size);
}

void FileDumpData::WriteData(const uint8_t *data, int length)
{

}

void PrintPacketInfo(AVFormatContext *avformat, AVPacket *packet)
{
    double dts_time = packet->dts * av_q2d(avformat->streams[packet->stream_index]->time_base);
    double pts_time = packet->pts * av_q2d(avformat->streams[packet->stream_index]->time_base);

    double duration = packet->duration * av_q2d(avformat->streams[packet->stream_index]->time_base);

    printf("dts time : %10lf\tpst time : %10lf\tduration time : %10lf\t pos : %10ld and stream index : %d.\n", dts_time, pts_time, duration, packet->pos, packet->stream_index);

}

void PrintFrameInfo(AVCodecContext * avcodec, AVFrame *frame)
{

    AVRational time_base = avcodec->pkt_timebase;
    double pkt_dts   = frame->pkt_dts * av_q2d(time_base);
    double pts_time  = frame->pts * av_q2d(time_base);

    double best_effort_time = frame->best_effort_timestamp * av_q2d(time_base);

    int is_key_frame = -1; 
    std::string pict_type_name;
    std::string format_type_name;
    if (avcodec->codec->type == AVMEDIA_TYPE_VIDEO)
    {
        is_key_frame = frame->key_frame;
        pict_type_name = av_get_picture_type_char(frame->pict_type);

        char buff[10] = {0};
        av_get_pix_fmt_string(buff, sizeof(buff), (AVPixelFormat)frame->format);
        format_type_name = buff;
    }
    else
    {
        is_key_frame = frame->key_frame;
        char buff[12];
        av_get_sample_fmt_string(buff, sizeof(buff), (AVSampleFormat)frame->format);
        format_type_name = buff;
        pict_type_name = "none";
    }
    printf("best effort time : %10lf\tpts time : %10lf\tpkt dts : %10lf\tkey frame : %4d\tpict type name : %4s\tformat type name : %s.\n", 
        best_effort_time, pts_time, pkt_dts, is_key_frame, pict_type_name.c_str(), format_type_name.c_str());
}


